import React, {Component} from 'react';
import {Tab, Table, Tabs} from "react-bootstrap";
import { browserHistory } from 'react-router';
import dagreD3 from "dagre-d3";
import d3 from "d3";

class WorkflowMetaDraw extends Component {
    constructor(props) {
        super(props);

        this.grapher = new dagreD3.render();

        this.setSvgRef = elem => this.svgElem = elem;
        this.state ={
            selectNode:"",
            allEdge:[],
            allNode:[],
            haveFinal:false,
        };
        let starPoints = function (outerRadius, innerRadius) {
            var results = "";
            var angle = Math.PI
                / 8;
            for (var i = 0; i < 2 * 8; i++) {
                // Use outer or inner radius depending on what iteration we are in.
                var r = (i & 1) == 0 ? outerRadius : innerRadius;
                var currX = 0 + Math.cos(i * angle) * r;
                var currY = 0 + Math.sin(i * angle) * r;
                if (i == 0) {
                    results = currX + "," + currY;
                } else {
                    results += ", " + currX + "," + currY;
                }
            }
            return results;
        };

        this.grapher.shapes().house = function (parent, bbox, node) {
            var w = bbox.width,
                h = bbox.height,
                points = [
                    {x: 0, y: 0},
                    {x: w, y: 0},
                    {x: w, y: -h},
                    {x: w / 2, y: -h * 3 / 2},
                    {x: 0, y: -h}
                ];
            let shapeSvg = parent.insert("polygon", ":first-child")
                .attr("points", points.map(function (d) {
                    return d.x + "," + d.y;
                }).join(" "))
                .attr("transform", "translate(" + (-w / 2) + "," + (h * 3 / 4) + ")");

            node.intersect = function (point) {
                return dagreD3.intersect.polygon(node, points, point);
            };

            return shapeSvg;
        };

        this.grapher.shapes().star = function (parent, bbox, node) {
            var w = bbox.width,
                h = bbox.height,
                points = [
                    {x: 0, y: 0},
                    {x: w, y: 0},
                    {x: w, y: -h},
                    {x: w / 2, y: -h * 3 / 2},
                    {x: 0, y: -h}
                ];
            let shapeSvg = parent.insert("polygon", ":first-child").attr("points", starPoints(w, h))
            node.intersect = function (point) {
                return dagreD3.intersect.polygon(node, points, point);
            };

            return shapeSvg;
        };

    }

    componentWillReceiveProps(nextProps) {
        var h = false;
        for(var a in nextProps.meta){
            if(nextProps.meta[a].ref == "final"){
                h = true;
            }
        }
        this.setState({
            allNode: nextProps.meta,
            allEdge: nextProps.allEdge,
            selectNode: nextProps.startNodeName,
            haveFinal: h
        });
    };


    render() {
        const { allEdge, allNode,layout,haveFinal } = this.state;
        const {updateNodeName,addInsertJoinLine} = this.props;
        let g = new dagreD3.graphlib.Graph().setGraph({rankdir: layout});
        allEdge.forEach(e => {
            g.setEdge(e.from, e.to, {label: e.label, lineInterpolate: 'basis', style: e.style});
        });
        for (let vk in allNode) {
            console.log(allNode[vk].ref);
            g.setNode(allNode[vk].ref, {
                label: allNode[vk].label,
                shape: allNode[vk].shape,
                type: allNode[vk].type,
                style: allNode[vk].style,
                labelStyle: allNode[vk].labelStyle
            });
        }
        let svg = d3.select(this.svgElem);
        let inner = svg.select("g");
        this.grapher(inner, g);
        let p = this;
        let w = g.graph().width + 200;
        let h = g.graph().height + 50;

        svg.attr("width", w + "px").attr("height", h + "px");

        let gNode = inner.selectAll("g.node");
        gNode.on("click",function(v){
            if(haveFinal){
                return;
            }
            let node = g.node(v);
            if(p.state.selectNode != ''){
                if(node.type == "JOIN"){
                    addInsertJoinLine(p.state.selectNode.split("|")[0],v);
                    return;
                }
                let ss = p.state.selectNode.split("|");
                let n = g.node(ss[0]);
                if(n != undefined){
                    n.style=ss[1];
                    if(ss[0] != v){
                        p.state.selectNode =v + "|" + node.style;
                    }
                }else {
                    p.state.selectNode =v + "|" + node.style;
                }
            }else{
                p.state.selectNode =v + "|" + node.style;
            }
            node.style='fill: #f0f';
            updateNodeName(v);
            p.grapher(inner, g);
        })

        return (
            <div className="graph-ui-content" id="graph-ui-content">
                <div style={{overflowX: "auto", width:"100%"}}>
                    <svg ref={this.setSvgRef}>
                        <g transform="translate(20,20)"/>
                    </svg>
                </div>
            </div>
        );
    }
}

export default WorkflowMetaDraw;
